/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ceair.flight.refund.util;

import com.ceair.muibe.provider.MBEConstant;
import com.ceair.muibe.provider.tkt.DetrSegment;
import com.ceair.muibe.provider.tkt.DetrTktInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @author Colin_You
 */
public final class DetrHelper {

    private static final Logger LOG = LoggerFactory.getLogger(DetrHelper.class);
    private static final String STATUS_OPEN_FOR_USE = "OPEN FOR USE";
    private static final String STATUS_CHECKED_IN = "CHECKED IN";
    private static final String STATUS_AIRP_CNTL = "AIRP CNTL";
    private final DetrTktInfo detr;
    private boolean refundable;
    private DetrSegment firstRefundableSeg;
    private DetrSegment firstUnusedSeg;
    private String ticketStatusString;

    public DetrHelper(final DetrTktInfo detr) {
        if (detr == null) {
            throw new IllegalArgumentException("Argument detr is empty");
        }
        this.detr = detr;
        parseDetr(this.detr);
    }

    public static DetrHelper combineHelpers(List<DetrHelper> helperList) {
        int helperLength = helperList.size();
        if (helperLength == 1) {
            return helperList.get(0);
        }
        DetrHelper refundableHelper = null;
        for (int i = helperLength - 1; i >= 0; i--) {
            DetrHelper tmpHelper = helperList.get(i);
            if (tmpHelper.isRefundable()) {
                refundableHelper = tmpHelper;
            }
        }
        //如果没有可退Detr, 就返回第一个detr
        return refundableHelper != null ? refundableHelper : helperList.get(0);
    }

    public boolean isRefundable() {
        return refundable;
    }

    public DetrTktInfo getDetr() {
        return detr;
    }

    public int getFirstRundableIndex() {
        return this.firstRefundableSeg == null ? -1 : this.firstRefundableSeg.getSegmentIndex();
    }

    public DetrSegment getFirstUnusedSegment() {
        return firstUnusedSeg;
    }

    public DetrSegment getFirstRefundableSegment() {
        return firstRefundableSeg;
    }

    public String getFirstRefundableTicketNo() {
        return detr.getTicketNo();
    }

    public String getFirstRefundableDepAirport() {
        return getFirstRefundableSegment().getDepAirportCode();
    }

    public String getFirstRefundableArrAirport() {
        return getFirstRefundableSegment().getArrAirportCode();
    }

    public String getFirstRefundableAirportPair() {
        return getFirstRefundableDepAirport() + getFirstRefundableArrAirport();
    }

    public String getTicketStatusString() {
        return ticketStatusString;
    }

    /**
     * 检查客票所有航段的状态
     *
     * @return
     */
    private void parseDetr(DetrTktInfo detr) {
        final String ticketNo = detr.getTicketNo();
        List<DetrSegment> segments = detr.getAirSegs();
        int segmentSize = segments.size();
        LOG.debug("Ticket No:{} has segments size:{}", ticketNo, segmentSize);
        DetrSegment firstUnusedSegment = null;
        DetrSegment refundableSegment = null;
        boolean refundableStatus = true;
        StringBuilder detrString = new StringBuilder(String.format("%s%n", ticketNo));
        for (int i = segmentSize - 1; i >= 0; i--) {
            DetrSegment segment = segments.get(i);
            int segType = segment.getType();
            String tktStatus = segment.getTicketStatus();
            detrString.append(segmentAsString(segment));
            if (MBEConstant.PNRAIRSEG_TYPE_ARNK == segType) {
                //忽略缺口航段
            } else if (STATUS_OPEN_FOR_USE.equalsIgnoreCase(tktStatus) || tktStatus.startsWith(STATUS_AIRP_CNTL)) {
                if (refundableStatus) {
                    refundableSegment = segment;
                }
                firstUnusedSegment = segment;
            } else {
                refundableStatus = false;
            }
        }
        this.firstUnusedSeg = firstUnusedSegment;
        this.ticketStatusString = detrString.toString();
        if (refundableSegment != null) {
            this.refundable = refundableSegment.getSegmentIndex() > 0;
            this.firstRefundableSeg = refundableSegment;
        } else {
            LOG.info("Ticket {} is not refundable", ticketNo);
        }
    }

    private String segmentAsString(DetrSegment segment) {
        String tktStatus = segment.getTicketStatus();
        String segStatus = segment.getSegmentStatus();
        final String depAirportCode = segment.getDepAirportCode();
        final String arrAirportCode = segment.getArrAirportCode();
        String segmentPair = depAirportCode + arrAirportCode;
        final int index = segment.getSegmentIndex();
        LOG.info("segment:{}:{} type:{} ticket status:{} segment status is:{}", index, segmentPair, segment.getType(), tktStatus, segStatus);
        return String.format("%d %s %s%n", index, segmentPair, tktStatus);
    }
}
